// 用于密码加密的库，它使用哈希函数将密码转换为一段随机字符串
const bcrypt = require('bcryptjs')
// const md5 = require('md5');

const { getUserInfo } = require('../service/user.service');
const { errorRequest } = require('../utils/util');
const { userFormatteError, userAlreadyExisted, rejectRegisterError, userDoesNotExist, userLoginError, invalidPassword } = require('../constant/err.type');
const userValidator = async (ctx, next) => {
  const { user_name, password } = ctx.request.body;
  if (!user_name || !password) {
    ctx.app.emit('error', userFormatteError, ctx);
    return;
  }
  await next();
}

const verifyUser = async (ctx, next) => {
  const { user_name } = ctx.request.body;
  try {
    const res = await getUserInfo({ user_name });
    if (res) {
      errorRequest(ctx, userAlreadyExisted, `用户名已经存在 | ${user_name}`);
      return;
    }
  } catch (error) {
    errorRequest(ctx, rejectRegisterError, '获取用户信息失败');
    return;
  }
  await next();
}

const cryptPassword = async (ctx, next) => {
  const { password } = ctx.request.body;
  // bcrypt.genSaltSync 用于生成一个随机的salt(盐值)，用于密码的哈希加密
  const salt = bcrypt.genSaltSync(10);
  // hash 保存的是密文
  const hash = bcrypt.hashSync(password, salt); // 同步将密码进行哈希加密 salt为哈希的次数 一般 10 ~ 21

  ctx.request.body.password = hash;
  await next();
};

const verityLogin = async (ctx, next) => {
  // 1.判断用户是否存在(不存在:报错)
  const { user_name, password } = ctx.request.body;
  try {
    const res = await getUserInfo({ user_name });
    if (!res) {
      errorRequest(ctx, userDoesNotExist, `用户名不存在 | ${user_name}`);
      return;
    }
    // 同步地比较密码和哈希字符串是否匹配，返回一个布尔值
    if (!bcrypt.compareSync(password, res.password)) {
      errorRequest(ctx, invalidPassword, `账号密码不匹配 | ${user_name}`);
      return;
    }
    await next();
  } catch (error) {
    errorRequest(ctx, userLoginError, `${error} | ${user_name}`);
    return;
  }
}

module.exports = {
  userValidator,
  verifyUser,
  cryptPassword,
  verityLogin
}